package com.demo.webflux.spring5core.framework.aop.aspect;

import java.lang.reflect.Method;

/**使用模板设计模式，封装拦截器回调的通用逻辑，主要封装反射动态调用方法，其子类只需要控制调用顺序即可
 * @author zhangsulei
 *
 */
public abstract class AbstractAspectAdvice implements Advice {

	private Method aspectMethod;
	private Object aspectTarget;

	public AbstractAspectAdvice(Method aspectMethod, Object aspectTarget) {
		this.aspectMethod = aspectMethod;
		this.aspectTarget = aspectTarget;
	}

	// 反射动态调用方法
	protected Object invokeAdviceMethod(JoinPoint joinPoint, Object returnValue, Throwable ex) throws Throwable {
		Class<?>[] paramsTypes = aspectMethod.getParameterTypes();
		if(null == paramsTypes || paramsTypes.length == 0) {
			return aspectMethod.invoke(aspectTarget);
		}else {
			Object[] args = new Object[paramsTypes.length];
			for (int i = 0; i < paramsTypes.length; i++) {
				if(paramsTypes[i] == JoinPoint.class) {
					args[i] = joinPoint;
				}else if(paramsTypes[i] == Throwable.class) {
					args[i] = ex;
				}else if(paramsTypes[i] == Object.class) {
					args[i] = returnValue;
				}
			}
			return aspectMethod.invoke(aspectTarget, args);
		}
	}

}
